﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Objects;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcJE.Core.Inet;
using MvcJE.Core.Models;
using MvcJE.Core.Helpers;
using MvcJE.Core.Extensions;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Script.Serialization;

namespace MvcJE.Web.Areas.Inet.Controllers
{
    public class TemplateMgrController : Controller
    {
        private IPServiceDb db = new IPServiceDb();

        //
        // GET: /Inet/TemplateMgr/

        public ViewResult Index(int start = 0, int itemsPerPage = 20, string orderBy = "Title", bool desc = false)
        {
         //   var a = db.MopModuleCategory.Count();
          //  var b = a;
            ViewBag.Count = db.MopModule.Count();
            ViewBag.Start = start;
            ViewBag.ItemsPerPage = itemsPerPage;
            ViewBag.OrderBy = orderBy;
            ViewBag.Desc = desc;

            return View();
        }

        [HttpPost]
        public ViewResult Index(int start = 0, int itemsPerPage = 20, string orderBy = "Title", bool desc = false, string kw="")
        {
            if (!String.IsNullOrEmpty(kw))
            {
                var data=db.MopModule.Where(p => p.Title.Contains(kw));
                if (data != null)
                {
                    ViewBag.Count = data.Count();
                }
            }
            else
            {
                ViewBag.Count = db.MopModule.Count();
            }
            ViewBag.Start = start;
            ViewBag.ItemsPerPage = itemsPerPage;
            ViewBag.OrderBy = orderBy;
            ViewBag.Desc = desc;
            ViewBag.Kw = kw;
            return View();
        }

        //
        // GET: /Inet/TemplateMgr/GridData/?start=0&itemsPerPage=20&orderBy=MopModuleId&desc=true

        public ActionResult GridData(int start = 0, int itemsPerPage = 20, string orderBy = "Title", bool desc = false, string kw="")
        {
            Response.AppendHeader("X-Total-Row-Count", db.MopModule.Count().ToString());
            ObjectQuery<MopModule> mopmodule = (db as IObjectContextAdapter).ObjectContext.CreateObjectSet<MopModule>();

            mopmodule = mopmodule.OrderBy("it." + orderBy + (desc ? " desc" : ""));
            if (!String.IsNullOrEmpty(kw))
            {
                var m = mopmodule.AsQueryable<MopModule>().Where(p => p.Title.Contains(kw));
                return PartialView(m.Skip(start).Take(itemsPerPage));
            }
            return PartialView(mopmodule.Skip(start).Take(itemsPerPage));
        }

        //
        // GET: /Default5/RowData/5

        public ActionResult RowData(Guid id)
        {
            MopModule mopmodule = db.MopModule.Find(id);
            return PartialView("GridData", new MopModule[] { mopmodule });
        }

        //
        // GET: /Inet/TemplateMgr/Create

        public ActionResult Create()
        {
            MopModule mopmodule = new MopModule();
            mopmodule.DateCreated = DateTime.Now;
            mopmodule.DateUpdated = DateTime.Now;
            ViewBag.MopModuleGroupId = new SelectList(db.MopModuleGroup, "MopModuleGroupId", "Name", mopmodule.MopModuleGroupId);
          //  mopmodule.Template = System.IO.File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "App_Data\\DataStore\\Templates\\MOP-Template.txt");
            return PartialView("Edit", mopmodule);
        }

        //
        // POST: /Inet/TemplateMgr/Create

        [HttpPost]
        public ActionResult Create(MopModule mopmodule)
        {
            if (ModelState.IsValid)
            {
                mopmodule.MopModuleId = Guid.NewGuid();
                db.MopModule.Add(mopmodule);
                db.SaveChanges();
                //  return PartialView("GridData", new MopModule[] { mopmodule });
                return RedirectToAction("FullEdit", new { id = mopmodule.MopModuleId, partial="true" });
            }
            ViewBag.MopModuleGroupId = new SelectList(db.MopModuleGroup, "MopModuleGroupId", "Name", mopmodule.MopModuleGroupId);
            return PartialView("Edit", mopmodule);
        }

        //
        // GET: /Inet/TemplateMgr/Edit/5

        public ActionResult Edit(Guid id)
        {
            MopModule mopmodule = db.MopModule.Find(id);
            ViewBag.MopModuleGroupId = new SelectList(db.MopModuleGroup, "MopModuleGroupId", "Name", mopmodule.MopModuleGroupId);
            return PartialView(mopmodule);
        }

        //
        // POST: /Inet/TemplateMgr/Edit/5

        [HttpPost]
        public ActionResult Edit(MopModule mopmodule)
        {
            if (ModelState.IsValid)
            {
                db.Entry(mopmodule).State = EntityState.Modified;
                db.SaveChanges();
                return PartialView("GridData", new MopModule[] { mopmodule });
            }

            return PartialView(mopmodule);
        }


        public String display(Guid id)
        {
            // create holder for final data
            List<String> finishLines = new List<String>();
            StringBuilder sb = new StringBuilder();
            var template = db.MopModule.Find(id);
            var mop = "<h2><div id=\"mopTitle\"> " + template.Title + "</div></h2><br />" + template.Template;
            ViewBag.Title = template.Title;

            // Add color to the variables
            mop = mop.Replace("[{", "<span style=\"color:Red;font-weight:bold;\">[{").Replace("}]", "}]</span>");
            mop = mop.ColorizeCommentsWith(new string[] { "//", "!", "##" }, "color:Green").ColorizeCommentsWith(new string[] { "/*" }, "color:#3399FF").ToHtml();
            return mop;
        }

        public ActionResult FullEdit(Guid id, String partial)
        {
            MopModule mopmodule = db.MopModule.Find(id);
            ViewBag.MopModuleGroupId = new SelectList(db.MopModuleGroup, "MopModuleGroupId", "Name", mopmodule.MopModuleGroupId);
            if (partial == "true")
                return PartialView(mopmodule);
            return View(mopmodule);
        }

        //
        // POST: /MOPTool/TemplateMgr/Edit/5

        [HttpPost]
        public ActionResult FullEdit(MopModule mopmodule, string submit)
        {
            if (ModelState.IsValid)
            {
                db.Entry(mopmodule).State = EntityState.Modified;
                if (!String.IsNullOrEmpty(mopmodule.Template))
                {
                    mopmodule.DateUpdated = DateTime.Now;
                    if (submit != "Save")
                    {
                        List<KeyValue> keys = new List<KeyValue>();
                        foreach (var item in mopmodule.ParsedVariables)
                        {
                            KeyValue key = new KeyValue();
                            key.Id = Guid.NewGuid();
                            key.Key = item;
                            key.Value = "value";
                            key.Label = item;
                            keys.Add(key);
                        }
                        mopmodule.Attributes = keys.ToJsonString();
                    }
                    mopmodule.Template = mopmodule.Template.Replace("[(", "[{").Replace(")]", "}]");
                    db.SaveChanges();
                    // savr a  text copy of the template
                    Random rnd= new Random();
                    var rootPath = AppDomain.CurrentDomain.BaseDirectory + "App_Data\\DataStore\\Templates";
                    try
                    {
                        Directory.CreateDirectory(rootPath);
                    }
                    catch { }
                    System.IO.File.WriteAllText(String.Format("{0}\\{1}_{2:mm}.txt", rootPath,mopmodule.Title, DateTime.Now), mopmodule.Template);
                }
                return RedirectToAction("Index");
            }
            ViewBag.MopModuleGroupId = new SelectList(db.MopModuleGroup, "MopModuleGroupId", "Name", mopmodule.MopModuleGroupId);
            return View(mopmodule);
        }

        /// <summary>
        /// This will load saved data input and display the saved data
        /// </summary>
        /// <param name="id">Guid of the saved data</param>
        /// <returns></returns>
        public ActionResult RestoreMOP(Guid id)
        {
            var inputData = db.MopInputData.Find(id);

            JavaScriptSerializer ser = new JavaScriptSerializer();
            List<KeyDataModel> keys = ser.Deserialize<List<KeyDataModel>>(inputData.Data);

            var mop = db.MopModule.Find(inputData.MopModuleId);
           // var mopKeys = MOPHelper.ConvertKeyValueToKeyData(mop.Template.KeyParserToJSONString(),true);
            var mopKeys = mop.Template.KeyParserToJSONString().ConvertKeyValueToKeyData(true);
            List<KeyDataModel> memKeys = new List<KeyDataModel>();
            //List<KeyDataModel> compKeys = new List<KeyDataModel>();
            foreach (var item in mopKeys)
            {
                if (keys.Where(p => p.UniqueKey == item.UniqueKey).Count() > 0)
                {
                    memKeys.Add(keys.SingleOrDefault(p => p.UniqueKey == item.UniqueKey));
                    //compKeys.Add(keys.SingleOrDefault(p => p.UniqueKey == item.UniqueKey));
                }
                else
                {
                    memKeys.Add(item);
                }
                   
            }
            StringBuilder sb=new StringBuilder();
            // check which stored parametes are no longer mapped.
                foreach(var data in keys.Except(memKeys))
                {
                    sb.AppendFormat("The stored parameters <span style=\"color:Green;\">[(\"{0}\":\"{1}\")]</span> no longer valid for this template<br />",data.UniqueKey, data.InputValue);
                }
                ViewBag.KeyDataMessage=sb.ToString().Replace("[(","[{").Replace(")]","}]");
 
            ViewBag.MopId = mop.MopModuleId;
            ViewBag.MopTitle = mop.Title;
            return View("CreateMOP", memKeys);
        }

        public ActionResult CreateMOP(Guid id)
        {
            var mop = db.MopModule.Find(id);
            var r1 = mop.Template.KeyParserToJSONString();
         //   var keys = MOPHelper.ConvertKeyValueToKeyData(r1, true);
            var keys = r1.ConvertKeyValueToKeyData(true);
            ViewBag.MopId = id;
            ViewBag.MopTitle = mop.Title;
            return View(keys);
        }

        [HttpPost]
        public MvcHtmlString CreateMOP(Guid id, List<KeyDataModel> param)
        {
            var button = Request["submit"];
            var saveTitle = Request["saveTitle"];
            var mop = db.MopModule.Find(id);
            var m = mop.Template;
            var message = String.Empty;
            if (!String.IsNullOrEmpty(saveTitle) && button == "Save Data Entries")
            {
                try
                {
                    MopInputData data = new MopInputData();
                    data.MopInputDataId = Guid.NewGuid();
                    data.DateCreated = DateTime.Now;
                    data.Title = saveTitle + String.Format("_{0:yyyyMMddmmss}", DateTime.Now);
                    JavaScriptSerializer serializer = new JavaScriptSerializer();
                    StringBuilder sb = new StringBuilder();
                    data.Data = serializer.Serialize(param);
                    data.MopModuleId = id;
                    db.MopInputData.Add(data);
                    db.SaveChanges();

                    message = "<span style=\"Color:Green\">Saved Successfully on " + DateTime.Now.ToString() + " with title: " + data.Title + "</span><br />";
                }
                catch (Exception ex)
                {
                    message = "<span style=\"Color:Red\">Error saving data on " + DateTime.Now.ToString() + ex.Message + "</span><br />";
                }
            }
            var keys = m.KeyParserToJSONString();
            var keyvals = keys.ConvertKeyValueToKeyData();

            // let's get the input value and assign to original parameters. We have to do this because the input data are distinct paramaters
            foreach (var item in keyvals)
            {
                var varData = param.SingleOrDefault(p => p.UniqueKey == item.UniqueKey);
                if (varData != null)
                {
                    item.InputValue = varData.InputValue;

                    if (!string.IsNullOrEmpty(item.CalculatedValue))
                    {
                        m = m.Replace(item.UserKeyValue, item.CalculatedValue);
                    }
                }
            }
            // Add color to the variables
            m = m.Replace("[{", "<span style=\"color:Red;font-weight:bold;\">[{").Replace("}]", "}]</span>");
            m = m.ColorizeCommentsWith(new string[] { "//" }, "color:Green; font-weight:bold").ColorizeCommentsWith(new string[] { "/*" }, "color:#3399FF");
            // Some wiki formatting but we need better way in next releases.
            m = m.Wikinize(new string[] { "!!!!" }, "<h4 style=\"color:#333333\">", "</h4>").Wikinize(new string[] { "!!!" }, "<h3 style=color:\"#333333\">", "</h3>").Wikinize(new string[] { "!!" }, "<h2 style=\"color:#333333\">", "</h2>");
            m = message + "<h2><div id=\"mopTitle\"> " + mop.Title + "</div></h2><br />" + m;
            return MvcHtmlString.Create(m.ToHtml());
        }

        [HttpPost]
        [ValidateInput(false)]
        public String SaveMOP(String title, String mop)
        {
            var ret = "Save Successfully ";
            var rootPath = AppDomain.CurrentDomain.BaseDirectory + "App_Data\\DataStore\\Configs\\" + String.Format("{0:yyyy}\\",DateTime.Now);
            var fileName = title.ToSlug() + String.Format("_{0:yyyyMMddmmss}_config", DateTime.Now) + ".htm";
            if ((String.IsNullOrEmpty(title)))
                title = "Configuration Methods Of Procedures";
            try
            {
                try
                {
                    Directory.CreateDirectory(rootPath);
                }
                catch { }

                System.IO.File.WriteAllText(rootPath + fileName, mop);
            }
            catch
            {
                ret = "Unable to save! Error saving file!";
            }


            return ret;
        }

         public ActionResult Help()
        {

            //    ViewBag.Help=System.IO.File.ReadAllLines(AppDomain.CurrentDomain.BaseDirectory + "App_Data\\DataStore\\Help\\help.txt");
            return View();
        }

        public ExcelResult ExportToExcel()
        {
            var mops = db.MopModule;

            System.Web.UI.WebControls.GridView grd = new System.Web.UI.WebControls.GridView();
            grd.DataSource = mops.ToList();
            grd.DataBind();

            StringWriter swr = new StringWriter();

            System.Web.UI.HtmlTextWriter tw = new System.Web.UI.HtmlTextWriter(swr);

            grd.RenderControl(tw);

            return new ExcelResult { FileName = "MOP.xls", XMLStream = swr.ToString() };
        }

        //
        // POST: /Inet/TemplateMgr/Delete/5

        [HttpPost]
        public void Delete(Guid id)
        {
            MopModule mopmodule = db.MopModule.Find(id);
            db.MopModule.Remove(mopmodule);
            db.SaveChanges();
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}
